#ifndef BASE163264_BASEXX_H
#define BASE163264_BASEXX_H
#include <iostream>
#include <string>
#include <string.h>
#include <vector>

using namespace std;

class BASE16
{
public:
    char* table_int2char;
    vector<int> table_char2int;

    BASE16() {
        table_int2char = "0123456789ABCDEF";
        table_char2int = vector<int>{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
             0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15};
    }
            
    string encode(const char *s, unsigned long long len)
    {
        // BASE16是4位一取，一个字节有8位，所以说一个字节拆成了两个字节，数据的最小单位为字节，所以一定可以成功加密
        string ans="";
        unsigned long long unll_len = len;
        // string 的最大长度除以2，得到最多能处理多少个字符
        const unsigned long long max_size = ans.max_size()>>1;
        const int t4 = 0x0F;
        for(unsigned long long i=0;i<unll_len&&i<max_size;i++)
        {
            ans+=table_int2char[(s[i]>>4)&t4];
            ans+=table_int2char[s[i]&t4];
        }
        return ans;
    }

    string encode(const string &s)
    {
        string ans="";
        unsigned long long unll_len = s.size();
        const unsigned long long max_size = ans.max_size()>>1;
        const int t4 = 0x0F;
        for(unsigned long long i=0;i<unll_len&&i<max_size;i++)
        {
            ans+=table_int2char[(s[i]>>4)&t4];
            ans+=table_int2char[s[i]&t4];
        }
        return ans;
    }

    string decode(const char *s, unsigned long long len)
    {
        string ans="";
        // string 的最大长度乘以2，得到最多能处理多少个字符
        const unsigned long long max_size = ans.max_size()<<1;
        unsigned long long p=0;
        // 取两个字符，拼成一个即可
        while(p+1<len&&p<max_size)
        {
            ans+=char((table_char2int[s[p]]<<4)+table_char2int[s[p+1]]);
            p+=2;
        }
        return ans;
    }

    string decode(const string &s)
    {
        string ans="";
        const unsigned long long max_size = ans.max_size()<<1;
        unsigned long long p=0;
        while(p+1<s.size()&&p<max_size)
        {
            ans+=char((table_char2int[s[p]]<<4)+table_char2int[s[p+1]]);
            p+=2;
        }
        return ans;
    }
};

#endif //BASE163264_BASEXX_H